from typing import Any, Callable, Optional
from fastapi import params
from fastapi import Depends
from jwt import PyJWTError

from pydantic import ValidationError
import jwt
from fastapi import Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from app.conf.config import settings
from app.core.database import DBSession
from app.core.exception.custom_error import UserNotExist
from app.core.exception.errors import TokenExpired, TokenError
from app.crud.admin_cruds.shop_user_crud import crud_shop_user
from app.models.shop.shop import User

security = HTTPBearer()


async def get_current_user(request: Request, db: DBSession, credentials: HTTPAuthorizationCredentials = Depends(security)) -> User:
    """
    通过token获取当前用户
    :param request:
    :param db:
    :param credentials:
    :return:
    """
    try:
        token = credentials.credentials
        # 解密token
        payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
        # 用户id
        user_id = payload.get("user_id")
        current_user = await crud_shop_user.get_row(db=db, key="user_id", value=user_id)
        if not current_user:
            raise UserNotExist()

        request.state.user = current_user
        return current_user

    except jwt.ExpiredSignatureError:
        raise TokenExpired()

    except jwt.InvalidTokenError:
        raise TokenError()

    except (PyJWTError, ValidationError):
        raise TokenError()

